package com.xz.supplierOrder.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.xz.common.core.domain.model.LoginUser;
import com.xz.common.exception.ServiceException;
import com.xz.common.utils.DateUtils;
import com.xz.common.utils.RedisCode;
import com.xz.common.utils.SecurityUtils;
import com.xz.common.utils.StringUtils;
import com.xz.logistics.enums.LogisticsModuleEnum;
import com.xz.logistics.service.ILogisticsService;
import com.xz.supplier.domain.Supplier;
import com.xz.supplier.mapper.SupplierMapper;
import com.xz.supplierContract.domain.SupplierContract;
import com.xz.supplierContract.service.ISupplierContractService;
import com.xz.supplierOrder.domain.SupplierOrder;
import com.xz.supplierOrder.dto.SupplierOrderDetailDto;
import com.xz.supplierOrder.dto.SupplierOrderDto;
import com.xz.supplierOrder.enums.SupplierOrderStatusEnum;
import com.xz.supplierOrder.enums.SupplierOrderTypeEnum;
import com.xz.supplierOrder.mapper.SupplierOrderMapper;
import com.xz.supplierOrder.service.ISupplierOrderDetailService;
import com.xz.supplierOrder.service.ISupplierOrderService;
import com.xz.supplierOrder.service.ISupplierOrderTypeFactoryService;
import com.xz.system.service.ISysDictDataService;
import com.xz.warehouse.domain.Warehouse;
import com.xz.warehouse.service.IWarehouseService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;

/**
 * 贸易中间商订单Service业务层处理
 *
 * @author xz
 * @date 2024-02-27
 */
@Service
public class SupplierOrderServiceImpl extends ServiceImpl<SupplierOrderMapper, SupplierOrder> implements ISupplierOrderService {
	@Autowired
	private SupplierOrderMapper supplierOrderMapper;
	@Autowired
	private SupplierMapper supplierMapper;
	@Autowired
	private ISupplierOrderDetailService supplierOrderDetailService;
	@Autowired
	private ISupplierContractService supplierContractService;
	@Autowired
	private ISysDictDataService sysDictDataService;
	@Autowired
	private ISupplierOrderTypeFactoryService supplierOrderTypeFactoryService;
	@Autowired
	private ILogisticsService logisticsService;
	@Autowired
	private IWarehouseService iWarehouseService;

	/**
	 * 查询贸易中间商订单
	 *
	 * @param id 贸易中间商订单主键
	 * @return 贸易中间商订单
	 */
	@Override
	public SupplierOrder selectSupplierOrderById(Long id) {
		return supplierOrderMapper.selectSupplierOrderById(id);
	}

	/**
	 * 查询贸易中间商订单列表
	 *
	 * @param supplierOrder 贸易中间商订单
	 * @return 贸易中间商订单
	 */
	@Override
	public List<SupplierOrder> selectSupplierOrderList(SupplierOrder supplierOrder) {
		return supplierOrderMapper.selectSupplierOrderList(supplierOrder);
	}

	/**
	 * 新增贸易中间商订单
	 *
	 * @param dto 贸易中间商订单
	 * @return 结果
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public int insertSupplierOrder(SupplierOrderDto dto) {
		// 校验前端提交的数据
		supplierOrderTypeFactoryService.verifyFields(dto);
		//开始新增
		SupplierOrder supplierOrder = new SupplierOrder();
		//填充订单类型
		supplierOrder.setOrderType(dto.getOrderType());
		//根据订单类型填充不同前缀的编号
		String no = RedisCode.getCode(SupplierOrderTypeEnum.noPrefixOf(dto.getOrderType()));
		supplierOrder.setOrderNo(no);
		//填充字段
		replaceFields(dto, supplierOrder);
		//填充创建人信息
		LoginUser user = SecurityUtils.getLoginUser();
		supplierOrder.setCreateBy(user.getUserId());
		supplierOrder.setCreateByName(user.getUsername());
		supplierOrder.setCreateTime(DateUtils.getNowDate());
		supplierOrder.setTenantId(user.getTenantId());
		supplierOrder.setDeptId(user.getDeptId());
		// 新增，先获取id，再做后续操作
		int flag = supplierOrderMapper.insertSupplierOrder(supplierOrder);
		if (flag > 0) {
			//保存订单详情（商品）数据
			supplierOrderDetailService.insertBatchForOrder(supplierOrder, dto);
			//最后判断状态，如果是想提交数据，则需要额外进行库存增加/扣减的操作
			if (SupplierOrderStatusEnum.SUBMITTED.getStatus() == supplierOrder.getOrderStatus()) {
				// 开始进行库存增加/扣减的操作
				supplierOrderTypeFactoryService.submitOrder(supplierOrder);
			}

			// 保存快递信息 -- 后面新加的模块，所以主表也有物流信息。
			logisticsService.saveByBusinessNo(
					LogisticsModuleEnum.SUPPLIER_ORDER.getModule(),
					supplierOrder.getId(),
					supplierOrder.getOrderNo(),
					supplierOrder.getOrderType(),
					dto.getLogistics()
			);
		}
		return flag;
	}

	/**
	 * 修改贸易中间商订单
	 *
	 * @param dto 贸易中间商订单
	 * @return 结果
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public int updateSupplierOrder(SupplierOrderDto dto) {

		SupplierOrder supplierOrder = supplierOrderMapper.selectById(dto.getId());
		//非提取库存状态
		Integer dbStatus = supplierOrder.getOrderStatus();
		if (SupplierOrderStatusEnum.SUBMITTED.getStatus() == dbStatus
				|| SupplierOrderStatusEnum.REVERSALED.getStatus() == dbStatus
				|| SupplierOrderStatusEnum.NULLIFIED.getStatus() == dbStatus
		) {
			throw new ServiceException("操作失败，当前状态无法执行修改操作。");
		}
		// 校验前端提交的数据
		dto.setBeforeStatus(dbStatus);
		supplierOrderTypeFactoryService.verifyFields(dto);
		//填充字段
		replaceFields(dto, supplierOrder);
		//填充更新人信息
		LoginUser user = SecurityUtils.getLoginUser();
		supplierOrder.setUpdateBy(user.getUserId());
		supplierOrder.setUpdateTime(DateUtils.getNowDate());
		int flag = supplierOrderMapper.updateSupplierOrder(supplierOrder);
		if (flag > 0) {
			//保存订单详情（商品）数据
			supplierOrderDetailService.updateBatchForOrder(supplierOrder, dto);
			//最后判断状态，如果不是保存为待提交，则需要额外进行库存增加/扣减的操作
			if (SupplierOrderStatusEnum.TO_BE_DELIVERY.getStatus() != supplierOrder.getOrderStatus()) {
				// set之前（数据库中）的状态，用作之后的逻辑处理。
				supplierOrder.setBeforeStatus(dbStatus);
				// 开始进行库存增加/扣减的操作
				supplierOrderTypeFactoryService.submitOrder(supplierOrder);
			}
			// 保存快递信息 -- 后面新加的模块，所以主表也有物流信息。
			logisticsService.saveByBusinessNo(
					LogisticsModuleEnum.SUPPLIER_ORDER.getModule(),
					supplierOrder.getId(),
					supplierOrder.getOrderNo(),
					supplierOrder.getOrderType(),
					dto.getLogistics()
			);
		}
		return flag;
	}


	/**
	 * 修改状态
	 *
	 * @param id
	 * @param orderStatus
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean editStatus(Long id, Integer orderStatus) {
		LambdaUpdateWrapper<SupplierOrder> wrapper = Wrappers.lambdaUpdate(SupplierOrder.class);
		wrapper.set(SupplierOrder::getOrderStatus, orderStatus);
		wrapper.set(SupplierOrder::getUpdateBy, SecurityUtils.getLoginUser().getUserId());
		wrapper.set(SupplierOrder::getUpdateTime, DateUtils.getNowDate());
		wrapper.eq(SupplierOrder::getId, id);
		return update(wrapper);
	}


	/**
	 * 作废单据
	 *
	 * @param id
	 * @return
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean nullifyOrder(Long id) {
		SupplierOrder supplierOrder = getById(id);
		if (null == supplierOrder) {
			throw new ServiceException("操作失败，单据不存在无法执行作废操作。");
		}
		if (SupplierOrderStatusEnum.TO_BE_DELIVERY.getStatus() != supplierOrder.getOrderStatus()) {
			throw new ServiceException("操作失败，当前状态无法执行作废操作。");
		}

		LambdaUpdateWrapper<SupplierOrder> wrapper = Wrappers.lambdaUpdate(SupplierOrder.class);
		wrapper.set(SupplierOrder::getOrderStatus, SupplierOrderStatusEnum.NULLIFIED.getStatus());
		wrapper.set(SupplierOrder::getUpdateBy, SecurityUtils.getLoginUser().getUserId());
		wrapper.set(SupplierOrder::getUpdateTime, DateUtils.getNowDate());
		wrapper.eq(SupplierOrder::getId, id);
		return update(wrapper);
	}

	/**
	 * 冲红单据
	 */
	@Override
	@Transactional(rollbackFor = Exception.class)
	public boolean reversalOrder(Long id) {
		SupplierOrder order = getById(id);
		if (null == order) {
			throw new ServiceException("操作失败，单据不存在无法执行冲红操作。");
		}
		Integer orderStatus = order.getOrderStatus();
		if (SupplierOrderStatusEnum.TO_BE_DELIVERY.getStatus() == orderStatus
				|| SupplierOrderStatusEnum.REVERSALED.getStatus() == orderStatus
				|| SupplierOrderStatusEnum.NULLIFIED.getStatus() == orderStatus
		) {
			throw new ServiceException("操作失败，当前状态无法执行冲红操作。");
		}
		// 开始冲红
		supplierOrderTypeFactoryService.reversalOrder(order);
		return true;
	}

	/**
	 * 替换字段
	 *
	 * @param dto
	 * @param supplierOrder
	 */
	private void replaceFields(SupplierOrderDto dto, SupplierOrder supplierOrder) {

		//换货方式：0-无,1-先退货后换货,2-先换货后退货
		if (null == dto.getExchangeMethod()) {
			supplierOrder.setExchangeMethod(0);
		} else {
			supplierOrder.setExchangeMethod(dto.getExchangeMethod());
		}

		// 赋值状态
		supplierOrder.setOrderStatus(dto.getOrderStatus());
		//填充合同信息
		supplierOrder.setContractId(dto.getContractId());
		SupplierContract contract = supplierContractService.getById(dto.getContractId());
		if (null != contract) {
			supplierOrder.setContractNo(contract.getContractNo());
			supplierOrder.setContractStartTime(contract.getContractStartTime());
			supplierOrder.setContractEndTime(contract.getContractEndTime());
		}
		//填充贸易中间商
		supplierOrder.setSupplierId(dto.getSupplierId());
		if (null != dto.getSupplierId()) {
			Supplier supplier = supplierMapper.selectById(dto.getSupplierId());
			if (null != supplier.getUnitName()) {
				supplierOrder.setSupplierName(supplier.getUnitName());
			}
		}
		supplierOrder.setAddress(dto.getAddress());
		supplierOrder.setContactPerson(dto.getContactPerson());
		supplierOrder.setContactInformation(dto.getContactInformation());
		//填充快递（物流）信息
		String expressDeliveryCompanies = dto.getExpressDeliveryCompanies();
		supplierOrder.setExpressDeliveryCompanies(expressDeliveryCompanies);
		if (!StringUtils.isEmpty(expressDeliveryCompanies)) {
			String deliveryCompaniesName = sysDictDataService.selectDictLabel("delivery_companies",
                    expressDeliveryCompanies);
			supplierOrder.setExpressDeliveryCompaniesName(deliveryCompaniesName);
		}
		supplierOrder.setExpressTrackingNumber(dto.getExpressTrackingNumber());
		supplierOrder.setExpressSenderPhone(dto.getExpressSenderPhone());
		supplierOrder.setExpressShippingTime(dto.getExpressShippingTime());
		supplierOrder.setExpressSender(dto.getExpressSender());
		//备注
		supplierOrder.setRemark(dto.getRemark());
		// 汇总字段，统计商品信息
		supplierOrder.setProductNum(dto.countTotalProductNum());
		supplierOrder.setPatientNames(dto.getPatientNames());

		if (!CollectionUtil.isEmpty(dto.getDeliveryDetails())) {
			dto.getDeliveryDetails().forEach(data -> {
				if (null != data.getWarehouseId()) {
					Warehouse warehouse = iWarehouseService.getById(data.getWarehouseId());
					if (null != warehouse) {
						data.setWarehouseName(warehouse.getWarehouseName());
					}
				}
			});
		}
		if (!CollectionUtil.isEmpty(dto.getReturnDetails())) {
			dto.getReturnDetails().forEach(data -> {
				if (null != data.getWarehouseId()) {
					Warehouse warehouse = iWarehouseService.getById(data.getWarehouseId());
					if (null != warehouse) {
						data.setWarehouseName(warehouse.getWarehouseName());
					}
				}
			});
		}
	}


}
